package kamikaze.utils;

import java.util.logging.Level;
import java.util.logging.Logger;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

public class Database {
	private static final Logger LOGGER = Logger.getLogger(Database.class.getName());
	private static final Database instance = new Database();
	private static final EntityManagerFactory emf =
			Persistence.createEntityManagerFactory("transactions-optional");

	public static Database get() {
		return instance;
	}

	public static interface Template<T> {

		T query(EntityManager em) throws Exception;

	}

	public <T> T execute(Template<T> template) {

		EntityManager em = emf.createEntityManager();
		EntityTransaction tx = em.getTransaction();

		try {
			tx.begin();
			T result = template.query(em);
			tx.commit();
			return result;
		} catch (Exception ex) {
			try {
				if (tx.isActive()) {
					tx.rollback();
				}
			} catch (Exception e) {
				LOGGER.log(Level.WARNING, "", e);
			}

			if (ex instanceof RuntimeException) {
				throw (RuntimeException) ex;
			} else {
				throw new RuntimeException(ex);
			}

		} finally {
			em.close();
		}
	}
}
